import { _decorator, Component, Node, Prefab, assetManager, AudioClip, AssetManager, Constructor, Asset, instantiate} from 'cc';
const { ccclass, property } = _decorator;

@ccclass('ResManager')
export class ResManager {
    constructor() {
    }

    loadPrefab(bundleName: string, prefabPath: string, callback:(prefeb: Prefab | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            bundle.load(prefabPath, Prefab, (err, prefab: Prefab) => {
                if (err) {
                    console.error(err);
                    callback(null);
                    return;
                }
                callback(prefab);
            })
        })
    }

    loadAudioClip(bundleName: string, audioPath: string, callback: (audioClip: AudioClip | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            bundle.load(audioPath, AudioClip, (err, audioClip: AudioClip) => {
                if (err) {
                    console.error("loadAudioClip error: ");
                    callback(null);
                    return;
                }
                callback(audioClip);
            })
        })
    }

    loadBundle(bundleName: string, callback?: (bundle: AssetManager.Bundle | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            callback && callback(bundle);
        })
    }

    loadBundleAsync(bundleName: string) {
        return new Promise((resolve, reject) => {
            assetManager.loadBundle(bundleName, (e, bundle) => {
                resolve(bundle);
            })
        })
    }

    loadAssetAsync<T extends Asset>(bundleName: string, path: string, type: Constructor<T>) {
        return new Promise<T>((resolve, reject) => {
            assetManager.loadBundle(bundleName, (e, bundle) => {
                bundle.load(path, type, (err, asset: T) => {
                    if (err) {
                        console.error("loadAssetAsync error: ", err);
                        resolve(null);
                        return;
                    }
                    resolve(asset);
                })
            })
        })
    }

    instantiate<UE extends Component>(ueClass: Constructor<UE>): UE {


        let node : Node = instantiate(prefab);
        return (node.getComponent(ueClass) || node.addComponent(ueClass)) as UE;
    }

}


